package com.ruoyi.framework.shiro.service;

import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.domain.SysThird;
import com.ruoyi.system.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @author renzhihao
 * @date 2023/11/29 14:16
 */
@Service
public class CommonAuthorizationService {
    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysThirdService thirdService;

    @Autowired
    private ISysConfigService configService;

    public SysUser getAndAddUserIfNotPresent(String username) {
        SysUser user = loginService.selectByLoginName(username);
        if (user == null) {
            String defaultPassword = configService.selectConfigByKey("sys.user.initPassword");

            synchronized (CommonAuthorizationService.class) {
                if (loginService.selectByLoginName(username) == null) {
                    SysRole commonRole = roleService.getCommonRole();
                    user = new SysUser();
                    user.setLoginName(username);
                    user.setUserName(username);
                    user.setPassword(defaultPassword);
                    user.setSex("2");
                    user.setRoleIds(List.of(commonRole.getRoleId()).toArray(new Long[0]));
                    userService.insertUser(user);
                }
            }
        }
        return user;
    }

    public AuthorizationInfo getAuthorizationInfo() {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        SysThird third = thirdService.selectThirdAuth();
        boolean ssoSync = Objects.equals(third.getSsoSync(), 0);
        String clientName = third.getClientName();

        SysUser user = ShiroUtils.getSysUser();
        if (user == null) {
            return info;
        }

        // 管理员拥有所有权限
        if (user.isAdmin()) {
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        } else if (ssoSync && StringUtils.equals(user.getClientName(), clientName)) {
            if (CollectionUtils.isNotEmpty(user.getRoleKeys())) {
                HashSet<String> roles = new HashSet<>(user.getRoleKeys());
                info.setRoles(roles);
                if (roles.contains("admin")) {
                    info.addStringPermission("*:*:*");
                }
            }

            if (CollectionUtils.isNotEmpty(user.getPermissionKeys())) {
                info.addStringPermissions(user.getPermissionKeys());
            }
        } else {
            Set<String> roles = roleService.selectRoleKeys(user.getUserId());
            Set<String> menus = menuService.selectPermsByUserId(user.getUserId());

            if (roles.contains("admin")) {
                info.addRole("admin");
                info.addStringPermission("*:*:*");
            } else {
                // 角色加入AuthorizationInfo认证对象
                info.setRoles(roles);

                // 权限加入AuthorizationInfo认证对象
                info.setStringPermissions(menus);
            }
        }
        return info;
    }
}
